package com.ts_xiaoa.ts_android_library.widget.indicator;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.ViewPager2;

import com.google.android.material.tabs.TabLayout;

import java.util.Objects;

/**
 * create by ts_xiaoa
 * create Time 2018/8/7
 * description: 自定义指示器indicator容器 配合ViewPager2使用 viewpager请使用原来写的那个
 */
public class TabIndicatorLayout2 extends FrameLayout {

    private View indicatorView;//指示器视图
    private int pageCount;//页面个数
    private IndicatorPageCallback indicatorPageCallback;
    private RecyclerView.AdapterDataObserver dataObserver;
    private ViewGroup tabParentLayout;
    private ViewPager2 viewPager2;
    //记录Indicator的宽度是否为MATCH_PARENT
    private boolean isMatchParent;

    public TabIndicatorLayout2(@NonNull Context context) {
        super(context);
    }

    public TabIndicatorLayout2(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public TabIndicatorLayout2(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (getChildCount() > 1) {
            throw new IllegalArgumentException("只能有一个indicator布局");
        }
        //得到当前容器（TabIndicatorLayout）的宽度
        //该viewGroup的宽度
        int parentWidth = getMeasuredWidth();
        //得到子View（TabIndicatorLayout内的指示器布局如：三角形、图片等等）
        indicatorView = getChildAt(0);
        //indicator三角形的宽度
        //指示器的宽度
        int indicatorWidth;
        if (indicatorView.getLayoutParams().width == LayoutParams.MATCH_PARENT
                && pageCount > 0) {
            indicatorWidth = getMeasuredWidth() / pageCount;
            ViewGroup.LayoutParams layoutParams = indicatorView.getLayoutParams();
            layoutParams.width = indicatorWidth;
            indicatorView.setLayoutParams(layoutParams);
        } else {
            indicatorWidth = indicatorView.getMeasuredWidth();
        }
        //得到指示器每次最大的偏移量（ViewPager翻页时，指示器滑动的距离）
        if (tabParentLayout != null && viewPager2 != null) {
            View currentTab = tabParentLayout.getChildAt(viewPager2.getCurrentItem());
//            if (isMatchParent && viewPager2.getCurrentItem() < viewPager2.getChildCount()) {
//                int leftWidth = tabParentLayout.getChildAt(viewPager2.getCurrentItem()).getMeasuredWidth();
//                int rightWidth = tabParentLayout.getChildAt(viewPager2.getCurrentItem() + 1).getMeasuredWidth();
//                int indicatorMatchWidth = (int) (rightWidth - leftWidth);
//                ViewGroup.LayoutParams layoutParams = indicatorView.getLayoutParams();
//                layoutParams.width = indicatorMatchWidth;
//                indicatorView.setLayoutParams(layoutParams);
//            }
            if (isMatchParent) {
                //用post中修改修改指示器的宽度 不然不会及时生效，界面无变化
                indicatorView.post(() -> {
                    indicatorView.setX(currentTab.getX());
                    ViewGroup.LayoutParams layoutParams = indicatorView.getLayoutParams();
                    layoutParams.width = tabParentLayout.getChildAt(viewPager2.getCurrentItem()).getMeasuredWidth();
                    indicatorView.setLayoutParams(layoutParams);
                });
            } else {
                indicatorView.setX(currentTab.getX() + (currentTab.getMeasuredWidth() >> 1) - (indicatorView.getMeasuredWidth() >> 1));
            }
        } else {
            if (pageCount != 0) {
                //设置indicator的第一个位置（如：indicator的容器宽度是100，viewpager的数量是5，indicator的宽度是4 那么indicator最开始的X = 100/4/2 - 4/2）
                indicatorView.setX(parentWidth / pageCount / 2 - (indicatorWidth >> 1));
            }
        }
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        //得到指示器indicator的视图
        indicatorView = getChildAt(0);
        //判断是否需要Indicator宽度全充满
        switch (indicatorView.getLayoutParams().width) {
            case LayoutParams.MATCH_PARENT:
                isMatchParent = true;//记录是否需要全充满
                break;
            default:
                isMatchParent = false;//记录是否需要全充满
                break;
        }
    }

    public void setUpWithViewPager(ViewGroup tabParent, ViewPager2 viewPager2) {
        this.tabParentLayout = tabParent;
        this.viewPager2 = viewPager2;
        setUpWithViewPager(viewPager2);
    }

    public void setUpWithViewPager(ViewPager2 viewPager2) {
        if (viewPager2.getAdapter() != null) {
            pageCount = viewPager2.getAdapter().getItemCount();
        }
        if (indicatorPageCallback != null) {
            viewPager2.unregisterOnPageChangeCallback(indicatorPageCallback);
        } else {
            indicatorPageCallback = new IndicatorPageCallback();
        }
        viewPager2.registerOnPageChangeCallback(indicatorPageCallback);
        if (viewPager2.getAdapter() != null) {
            if (dataObserver != null) {
                viewPager2.getAdapter().unregisterAdapterDataObserver(dataObserver);
            } else {
                dataObserver = new RecyclerView.AdapterDataObserver() {
                    @Override
                    public void onChanged() {
                        pageCount = viewPager2.getAdapter().getItemCount();
                    }
                };
            }
            Objects.requireNonNull(viewPager2.getAdapter()).registerAdapterDataObserver(dataObserver);
        }
    }

    private class IndicatorPageCallback extends ViewPager2.OnPageChangeCallback {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            moveIndicator(position, positionOffset);
        }
    }

    private void moveIndicator(int position, float positionOffset) {
        //判断当切换完成到最后一个pager时
        if (position == tabParentLayout.getChildCount() - 1) {
            //return,下面107行位置tabParentLayout.getChildAt(position + 1).getMeasuredWidth()会报NullPoint
            return;
        }
        //如果没有tab return
        if (tabParentLayout.getChildCount() == 0) return;
        /* *******************************indicator移动部分*********************************** */
        //得到当前TabItem的X坐标
        int currTabItemX = (int) tabParentLayout.getChildAt(position).getX();
        //得到当前TabItem的宽度
        int currTabItemWidth = tabParentLayout.getChildAt(position).getMeasuredWidth();
        //计算出当前Indicator的X 注：没有滑动时indicator的位置X
        int indicatorX = currTabItemX + currTabItemWidth / 2 - indicatorView.getMeasuredWidth() / 2;
        //得到indicator移动到下一个pager的总距离：(当前TabItem的宽度+下一个TabItem的宽度)/2
        int distance = (tabParentLayout.getChildAt(position + 1).getMeasuredWidth() + currTabItemWidth) / 2;
        //计算滑动viewpager时的偏移量：偏移比例 * 滑动到下一个pager的总距离
        int offset = (int) (positionOffset * (distance));
        if (tabParentLayout.getParent() instanceof TabLayout) {
            //得到TabLayout滑动的X
            int tabScrollX = ((TabLayout) tabParentLayout.getParent()).getScrollX();
            //计算得出滑动时indicator的X：原来的X+滑动的偏移量 - TabLayout滑动的X
            indicatorX += offset - tabScrollX;
        }
        indicatorX += offset;
        //重新设置当前indicator的X
        indicatorView.setX(indicatorX);
        /* *******************************indicator移动部分*********************************** */
        //如果indicator的宽度设置为MATCH_PARENT，每个TabItem的宽度不一样
        if (isMatchParent) {
            int leftWidth = tabParentLayout.getChildAt(position).getMeasuredWidth();
            int rightWidth = tabParentLayout.getChildAt(position + 1).getMeasuredWidth();
            int indicatorWidth = (int) (leftWidth + (rightWidth - leftWidth) * positionOffset);
            ViewGroup.LayoutParams layoutParams = indicatorView.getLayoutParams();
            layoutParams.width = indicatorWidth;
            indicatorView.setLayoutParams(layoutParams);
        }
        /* *******************************indicator宽度变化部分*********************************** */
    }

}
